#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import logging
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import TimeoutException, NoSuchElementException

from tests.page_objects.base_page import BasePage

class OrderPage(BasePage):
    """订单管理页面对象"""
    
    # 导航菜单定位器
    ORDER_MENU = (By.XPATH, "//span[text()='订单管理']")
    ORDER_LIST_MENU = (By.XPATH, "//li[contains(@class, 'el-menu-item')][.//text()='订单列表']")
    
    # 搜索表单定位器
    ORDER_NO_INPUT = (By.XPATH, "//label[text()='订单号']/following-sibling::div//input")
    STATUS_SELECT = (By.XPATH, "//label[text()='订单状态']/following-sibling::div//div[contains(@class, 'el-select')]")
    STATUS_SELECT_ALT = (By.CSS_SELECTOR, ".el-select__wrapper input[placeholder='请选择状态']")
    SEARCH_BUTTON = (By.XPATH, "//form[contains(@class, 'el-form')]//button[contains(@class, 'el-button--primary')][.//span[text()='搜索']]")
    RESET_BUTTON = (By.XPATH, "//form[contains(@class, 'el-form')]//button[.//span[text()='重置']]")
    
    # 表格定位器
    ORDER_TABLE = (By.XPATH, "//table[contains(@class, 'el-table')]")
    TABLE_ROWS = (By.XPATH, "//table[contains(@class, 'el-table')]//tbody/tr")
    TABLE_LOADING = (By.XPATH, "//div[contains(@class, 'el-loading-mask')]")
    
    # 发货按钮定位器
    FIRST_ROW_SHIP_BUTTON = (By.XPATH, "//table[contains(@class, 'el-table')]//tbody/tr[1]//button[contains(@class, 'el-button--success')][.//span[text()='发货']]")
    SHIP_BUTTON_ALT = (By.CSS_SELECTOR, "button.el-button--success.el-button--small")
    
    # 发货对话框定位器
    SHIP_DIALOG = (By.XPATH, "//div[contains(@class, 'el-dialog')][.//span[text()='订单发货']]")
    DIALOG_ORDER_NO = (By.XPATH, "//div[contains(@class, 'el-dialog')]//label[text()='订单号']/following-sibling::div//input")
    DIALOG_DELIVERY_COMPANY_SELECT = (By.XPATH, "//div[contains(@class, 'el-dialog')]//label[text()='快递公司']/following-sibling::div//div[contains(@class, 'el-select')]")
    DIALOG_TRACKING_NO_INPUT = (By.XPATH, "//div[contains(@class, 'el-dialog')]//label[text()='快递单号']/following-sibling::div//input")
    DIALOG_NOTES_TEXTAREA = (By.XPATH, "//div[contains(@class, 'el-dialog')]//label[text()='备注']/following-sibling::div//textarea")
    DIALOG_CONFIRM_BUTTON = (By.XPATH, "//div[contains(@class, 'el-dialog')]//button[contains(@class, 'el-button--primary')][.//span[text()='确认发货']]")
    DIALOG_CANCEL_BUTTON = (By.XPATH, "//div[contains(@class, 'el-dialog')]//button[.//span[text()='取消']]")
    
    # 下拉选项定位器
    DROPDOWN_ITEM = (By.XPATH, "//div[contains(@class, 'el-select-dropdown') and not(contains(@style, 'display: none'))]//div[contains(@class, 'el-select-dropdown__item')]")
    
    # 消息提示
    SUCCESS_MESSAGE = (By.CSS_SELECTOR, ".el-message--success")
    
    def __init__(self, driver):
        super().__init__(driver)
        self.actions = ActionChains(driver)
    
    def navigate_to_order_page(self):
        """
        导航到订单列表页面
        """
        logging.info("导航到订单列表页面")
        
        try:
            # 等待订单管理菜单可见并点击
            try:
                order_menu = self.wait.until(EC.element_to_be_clickable(self.ORDER_MENU))
                order_menu.click()
                logging.info("已点击订单管理菜单")
            except Exception as e:
                logging.warning(f"点击订单管理菜单失败: {e}")
                # 使用更通用的XPath
                try:
                    order_menu = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), '订单管理')]")))
                    order_menu.click()
                    logging.info("已使用通用XPath点击订单管理菜单")
                except Exception as e2:
                    logging.warning(f"使用通用XPath点击订单管理菜单失败: {e2}")
                    # 使用JavaScript点击
                    self.driver.execute_script("""
                    var menuItems = document.querySelectorAll('span');
                    for (var i = 0; i < menuItems.length; i++) {
                        if (menuItems[i].textContent.includes('订单管理')) {
                            menuItems[i].click();
                            console.log('已通过JavaScript点击订单管理菜单');
                            break;
                        }
                    }
                    """)
            
            # 等待子菜单展开
            time.sleep(2)
            
            # 点击订单列表子菜单
            try:
                order_list_menu = self.wait.until(EC.element_to_be_clickable(self.ORDER_LIST_MENU))
                order_list_menu.click()
                logging.info("已点击订单列表子菜单")
            except Exception as e:
                logging.warning(f"点击订单列表子菜单失败: {e}")
                # 使用更通用的XPath
                try:
                    order_list_menu = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//li[contains(@class, 'el-menu-item')][contains(., '订单列表')]")))
                    order_list_menu.click()
                    logging.info("已使用通用XPath点击订单列表子菜单")
                except Exception as e2:
                    logging.warning(f"使用通用XPath点击订单列表子菜单失败: {e2}")
                    # 使用JavaScript点击
                    self.driver.execute_script("""
                    var subMenuItems = document.querySelectorAll('li.el-menu-item');
                    for (var i = 0; i < subMenuItems.length; i++) {
                        if (subMenuItems[i].textContent.includes('订单列表')) {
                            subMenuItems[i].click();
                            console.log('已通过JavaScript点击订单列表子菜单');
                            break;
                        }
                    }
                    """)
            
            # 等待页面加载
            time.sleep(5)  # 增加等待时间
            
            try:
                self.wait.until(EC.presence_of_element_located(self.ORDER_TABLE))
                logging.info("订单列表页面已加载")
            except Exception as e:
                logging.warning(f"等待订单列表页面加载失败: {e}")
            
            # 截图
            self.take_screenshot("order_page_loaded")
            
            return self
        except Exception as e:
            logging.error(f"导航到订单列表页面失败: {e}")
            self.take_screenshot("navigate_to_order_page_failed")
            raise
    
    def search_order(self, order_no=None, status=None):
        """
        搜索订单
        
        Args:
            order_no: 订单号
            status: 订单状态
        """
        logging.info(f"搜索订单: 订单号={order_no}, 状态={status}")
        
        try:
            # 输入订单号
            if order_no:
                self.input_text(self.ORDER_NO_INPUT, order_no)
            
            # 选择订单状态
            if status:
                # 尝试多种方法点击状态下拉框
                try:
                    # 方法1: 使用主要定位器
                    logging.info("尝试点击订单状态下拉框")
                    self.click(self.STATUS_SELECT)
                except Exception as e1:
                    logging.warning(f"点击订单状态下拉框失败(方法1): {e1}")
                    try:
                        # 方法2: 使用备用CSS选择器
                        logging.info("尝试使用备用CSS选择器点击订单状态下拉框")
                        self.click(self.STATUS_SELECT_ALT)
                    except Exception as e2:
                        logging.warning(f"点击订单状态下拉框失败(方法2): {e2}")
                        try:
                            # 方法3: 使用JavaScript点击
                            logging.info("尝试使用JavaScript点击订单状态下拉框")
                            self.driver.execute_script("""
                            // 尝试通过placeholder找到元素
                            var statusInput = document.querySelector('input[placeholder="请选择状态"]');
                            if (statusInput) {
                                statusInput.click();
                                console.log('已通过placeholder点击订单状态下拉框');
                                return;
                            }
                            
                            // 尝试通过label找到元素
                            var labels = document.querySelectorAll('label');
                            for (var i = 0; i < labels.length; i++) {
                                if (labels[i].textContent.includes('订单状态')) {
                                    var select = labels[i].nextElementSibling.querySelector('.el-select');
                                    if (select) {
                                        select.click();
                                        console.log('已通过label找到并点击订单状态下拉框');
                                        return;
                                    }
                                }
                            }
                            """)
                        except Exception as e3:
                            logging.warning(f"使用JavaScript点击订单状态下拉框失败: {e3}")
                
                # 等待下拉选项出现
                time.sleep(2)
                
                # 尝试选择对应状态
                try:
                    # 构建多种可能的选项定位器
                    status_options = [
                        (By.XPATH, f"//div[contains(@class, 'el-select-dropdown__item')][.//span[text()='{status}']]"),
                        (By.XPATH, f"//div[contains(@class, 'el-select-dropdown__item')][text()='{status}']"),
                        (By.XPATH, f"//div[contains(@class, 'el-select-dropdown__item')][contains(., '{status}')]")
                    ]
                    
                    # 尝试点击选项
                    clicked = False
                    for option in status_options:
                        try:
                            if self.is_element_present(option):
                                self.click(option)
                                logging.info(f"已选择状态: {status}")
                                clicked = True
                                break
                        except Exception as e:
                            logging.warning(f"点击状态选项失败: {e}")
                    
                    # 如果上述方法都失败，尝试使用JavaScript
                    if not clicked:
                        logging.info("尝试使用JavaScript选择状态")
                        self.driver.execute_script(f"""
                        var items = document.querySelectorAll('.el-select-dropdown__item');
                        for (var i = 0; i < items.length; i++) {{
                            if (items[i].textContent.includes('{status}')) {{
                                items[i].click();
                                console.log('已通过JavaScript选择状态: {status}');
                                break;
                            }}
                        }}
                        """)
                except Exception as e:
                    logging.warning(f"选择订单状态失败: {e}")
            
            # 点击搜索按钮
            try:
                self.click(self.SEARCH_BUTTON)
                logging.info("已点击搜索按钮")
            except Exception as e:
                logging.warning(f"点击搜索按钮失败: {e}")
                # 尝试使用JavaScript点击搜索按钮
                self.driver.execute_script("""
                var buttons = document.querySelectorAll('button');
                for (var i = 0; i < buttons.length; i++) {
                    if (buttons[i].textContent.includes('搜索')) {
                        buttons[i].click();
                        console.log('已通过JavaScript点击搜索按钮');
                        break;
                    }
                }
                """)
            
            # 等待搜索结果加载
            time.sleep(3)
            
            # 等待加载动画消失
            try:
                WebDriverWait(self.driver, 10).until_not(
                    EC.presence_of_element_located(self.TABLE_LOADING)
                )
            except:
                logging.warning("等待加载动画消失超时")
            
            return self
        except Exception as e:
            logging.error(f"搜索订单失败: {e}")
            self.take_screenshot("search_order_failed")
            raise
    
    def reset_search(self):
        """
        重置搜索条件
        """
        logging.info("重置搜索条件")
        try:
            self.click(self.RESET_BUTTON)
            time.sleep(2)
            return self
        except Exception as e:
            logging.error(f"重置搜索失败: {e}")
            self.take_screenshot("reset_search_failed")
            raise
    
    def click_first_row_ship_button(self):
        """
        点击第一行的发货按钮
        """
        logging.info("点击第一行的发货按钮")
        
        try:
            # 等待表格加载完成
            self.wait.until(EC.presence_of_element_located(self.ORDER_TABLE))
            
            # 尝试点击发货按钮
            try:
                ship_button = self.wait.until(EC.element_to_be_clickable(self.FIRST_ROW_SHIP_BUTTON))
                ship_button.click()
                logging.info("已点击发货按钮")
            except Exception as e:
                logging.warning(f"点击发货按钮失败: {e}")
                
                # 尝试使用备用选择器
                try:
                    logging.info("尝试使用备用选择器点击发货按钮")
                    ship_button = self.wait.until(EC.element_to_be_clickable(self.SHIP_BUTTON_ALT))
                    ship_button.click()
                    logging.info("已使用备用选择器点击发货按钮")
                except Exception as e2:
                    logging.warning(f"使用备用选择器点击发货按钮失败: {e2}")
                    
                    # 尝试使用JavaScript点击
                    try:
                        logging.info("尝试使用JavaScript点击发货按钮")
                        self.driver.execute_script("""
                        // 方法1: 通过类名查找
                        var buttons = document.querySelectorAll('button.el-button--success.el-button--small');
                        if (buttons.length > 0) {
                            buttons[0].click();
                            console.log('已通过类名点击发货按钮');
                            return;
                        }
                        
                        // 方法2: 通过文本内容查找
                        var allButtons = document.querySelectorAll('button');
                        for (var i = 0; i < allButtons.length; i++) {
                            if (allButtons[i].textContent.includes('发货')) {
                                allButtons[i].click();
                                console.log('已通过文本内容点击发货按钮');
                                return;
                            }
                        }
                        """)
                    except Exception as e3:
                        logging.error(f"使用JavaScript点击发货按钮失败: {e3}")
                        self.take_screenshot("click_ship_button_failed")
                        raise
            
            # 等待发货对话框显示
            self.wait.until(EC.visibility_of_element_located(self.SHIP_DIALOG))
            logging.info("发货对话框已显示")
            
            # 截图
            self.take_screenshot("ship_dialog_opened")
            
            return self
        except Exception as e:
            logging.error(f"点击发货按钮或等待对话框显示失败: {e}")
            self.take_screenshot("ship_dialog_failed")
            raise
    
    def fill_shipping_form(self, delivery_company, tracking_no, notes=""):
        """
        填写发货表单
        
        Args:
            delivery_company: 快递公司
            tracking_no: 快递单号
            notes: 备注信息
        """
        logging.info(f"填写发货表单: 快递公司={delivery_company}, 快递单号={tracking_no}")
        
        try:
            # 选择快递公司
            try:
                self.click(self.DIALOG_DELIVERY_COMPANY_SELECT)
                logging.info("已点击快递公司下拉框")
            except Exception as e:
                logging.warning(f"点击快递公司下拉框失败: {e}")
                # 尝试使用JavaScript点击
                self.driver.execute_script("""
                // 尝试通过对话框和label查找元素
                var dialog = document.querySelector('.el-dialog');
                if (dialog) {
                    var labels = dialog.querySelectorAll('label');
                    for (var i = 0; i < labels.length; i++) {
                        if (labels[i].textContent.includes('快递公司')) {
                            var select = labels[i].nextElementSibling.querySelector('.el-select');
                            if (select) {
                                select.click();
                                console.log('已通过JavaScript点击快递公司下拉框');
                                break;
                            }
                        }
                    }
                }
                """)
            
            time.sleep(1)
            
            # 点击对应的快递公司选项
            try:
                # 构建多种可能的选项定位器
                company_options = [
                    (By.XPATH, f"//div[contains(@class, 'el-select-dropdown__item')][.//span[text()='{delivery_company}']]"),
                    (By.XPATH, f"//div[contains(@class, 'el-select-dropdown__item')][text()='{delivery_company}']"),
                    (By.XPATH, f"//div[contains(@class, 'el-select-dropdown__item')][contains(., '{delivery_company}')]")
                ]
                
                # 尝试点击选项
                clicked = False
                for option in company_options:
                    try:
                        if self.is_element_present(option):
                            self.click(option)
                            logging.info(f"已选择快递公司: {delivery_company}")
                            clicked = True
                            break
                    except Exception as e:
                        logging.warning(f"点击快递公司选项失败: {e}")
                
                # 如果上述方法都失败，尝试使用JavaScript
                if not clicked:
                    logging.info("尝试使用JavaScript选择快递公司")
                    self.driver.execute_script(f"""
                    var items = document.querySelectorAll('.el-select-dropdown__item');
                    for (var i = 0; i < items.length; i++) {{
                        if (items[i].textContent.includes('{delivery_company}')) {{
                            items[i].click();
                            console.log('已通过JavaScript选择快递公司: {delivery_company}');
                            break;
                        }}
                    }}
                    """)
            except Exception as e:
                logging.warning(f"选择快递公司失败: {e}")
            
            time.sleep(1)
            
            # 输入快递单号
            try:
                self.input_text(self.DIALOG_TRACKING_NO_INPUT, tracking_no)
            except Exception as e:
                logging.warning(f"输入快递单号失败: {e}")
                # 尝试使用JavaScript输入
                self.driver.execute_script(f"""
                var dialog = document.querySelector('.el-dialog');
                if (dialog) {{
                    var labels = dialog.querySelectorAll('label');
                    for (var i = 0; i < labels.length; i++) {{
                        if (labels[i].textContent.includes('快递单号')) {{
                            var input = labels[i].nextElementSibling.querySelector('input');
                            if (input) {{
                                input.value = '{tracking_no}';
                                input.dispatchEvent(new Event('input'));
                                console.log('已通过JavaScript输入快递单号');
                                break;
                            }}
                        }}
                    }}
                }}
                """)
            
            # 输入备注信息
            if notes:
                try:
                    self.input_text(self.DIALOG_NOTES_TEXTAREA, notes)
                except Exception as e:
                    logging.warning(f"输入备注信息失败: {e}")
                    # 尝试使用JavaScript输入
                    self.driver.execute_script(f"""
                    var dialog = document.querySelector('.el-dialog');
                    if (dialog) {{
                        var labels = dialog.querySelectorAll('label');
                        for (var i = 0; i < labels.length; i++) {{
                            if (labels[i].textContent.includes('备注')) {{
                                var textarea = labels[i].nextElementSibling.querySelector('textarea');
                                if (textarea) {{
                                    textarea.value = '{notes}';
                                    textarea.dispatchEvent(new Event('input'));
                                    console.log('已通过JavaScript输入备注信息');
                                    break;
                                }}
                            }}
                        }}
                    }}
                    """)
            
            # 截图
            self.take_screenshot("shipping_form_filled")
            
            return self
        except Exception as e:
            logging.error(f"填写发货表单失败: {e}")
            self.take_screenshot("fill_shipping_form_failed")
            raise
    
    def submit_shipping_form(self):
        """
        提交发货表单
        """
        logging.info("提交发货表单")
        
        try:
            # 点击确认发货按钮
            try:
                self.click(self.DIALOG_CONFIRM_BUTTON)
                logging.info("已点击确认发货按钮")
            except Exception as e:
                logging.warning(f"点击确认发货按钮失败: {e}")
                
                # 尝试使用JavaScript点击
                self.driver.execute_script("""
                var dialog = document.querySelector('.el-dialog');
                if (dialog) {
                    var buttons = dialog.querySelectorAll('button');
                    for (var i = 0; i < buttons.length; i++) {
                        if (buttons[i].textContent.includes('确认发货')) {
                            buttons[i].click();
                            console.log('已通过JavaScript点击确认发货按钮');
                            break;
                        }
                    }
                }
                """)
            
            # 等待对话框关闭
            try:
                WebDriverWait(self.driver, 10).until_not(
                    EC.visibility_of_element_located(self.SHIP_DIALOG)
                )
                logging.info("发货对话框已关闭")
            except TimeoutException:
                logging.warning("等待发货对话框关闭超时")
                
                # 尝试使用JavaScript关闭对话框
                try:
                    self.driver.execute_script("""
                    var confirmButton = document.querySelector('.dialog-footer .el-button--primary');
                    if (confirmButton) {
                        confirmButton.click();
                        console.log('已通过JavaScript点击确认按钮');
                    }
                    """)
                except Exception as e:
                    logging.error(f"使用JavaScript关闭对话框失败: {e}")
            
            # 等待成功消息显示
            try:
                self.wait.until(EC.visibility_of_element_located(self.SUCCESS_MESSAGE))
                logging.info("发货成功消息已显示")
                
                # 截图
                self.take_screenshot("shipping_success")
            except TimeoutException:
                logging.warning("未检测到成功消息")
            
            return self
        except Exception as e:
            logging.error(f"提交发货表单失败: {e}")
            self.take_screenshot("submit_shipping_form_failed")
            raise
    
    def cancel_shipping_form(self):
        """
        取消发货表单
        """
        logging.info("取消发货表单")
        
        try:
            # 点击取消按钮
            self.click(self.DIALOG_CANCEL_BUTTON)
            
            # 等待对话框关闭
            WebDriverWait(self.driver, 10).until_not(
                EC.visibility_of_element_located(self.SHIP_DIALOG)
            )
            logging.info("发货对话框已关闭")
            
            return self
        except Exception as e:
            logging.error(f"取消发货表单失败: {e}")
            self.take_screenshot("cancel_shipping_form_failed")
            raise
    
    def is_shipping_successful(self):
        """
        检查发货是否成功
        
        Returns:
            布尔值，表示发货是否成功
        """
        try:
            # 检查成功消息
            success = self.is_element_present(self.SUCCESS_MESSAGE)
            if success:
                message = self.get_text(self.SUCCESS_MESSAGE)
                logging.info(f"检测到成功消息: {message}")
            else:
                logging.warning("未检测到成功消息")
            
            return success
        except Exception as e:
            logging.error(f"检查发货是否成功时出错: {e}")
            return False 